package com.aleyn.router.inject.instance

import com.aleyn.router.inject.Core

/**
 * @author: Aleyn
 * @date: 2023/7/27 11:05
 *
 * 实例工厂的抽象基类。
 * 定义了创建和获取实例的基本行为。
 *
 * @param T 实例的类型。
 * @param definition 实例的定义信息。
 */
abstract class InstanceFactory<T>(val definition: Definition<T>) {

    /**
     * 获取一个实例。
     * 具体的获取逻辑（例如，是返回单例还是创建新实例）由子类实现。
     *
     * @param context 实例创建时所需的上下文信息。
     * @return 实例。
     */
    abstract fun get(context: InstanceData): T

    /**
     * 创建一个新实例。
     * 这是实际执行实例化的方法，它会调用 [Definition] 中定义的 lambda 表达式。
     *
     * @param context 实例创建时所需的上下文信息。
     * @return 创建的新实例。
     * @throws RuntimeException 如果实例创建失败。
     */
    open fun create(context: InstanceData): T {
        try {
            return definition.def.invoke(Core, context.parameters ?: Parameters())
        } catch (e: Exception) {
            throw RuntimeException("Could not create instance for '$definition'", e)
        }
    }

    /**
     * 检查实例是否已经被创建（主要用于单例）。
     *
     * @return 如果实例已创建则返回 true，否则返回 false。
     */
    abstract fun isCreated(): Boolean
}